package Etcd

import (
	"context"
	"encoding/json"
	"fmt"
	"logagent/Tailfile"
	"logagent/common"
	"time"

	"go.etcd.io/etcd/clientv3"
)

var (
	Client *clientv3.Client
)

func EtcdInit(address []string) (err error) {
	Client, err = clientv3.New(clientv3.Config{
		Endpoints:   address,
		DialTimeout: 5 * time.Second,
	})
	if err != nil {
		fmt.Printf("etcd init fail,err is %v", err)
	}

	// ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
	// _, err = Client.Put(ctx, "key1", "value1")
	// if err != nil {
	// 	fmt.Printf("etcd send fail,err is %v", err)
	// }
	// cancel()
	// ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second)
	// gr, err := Client.Get(ctx, "key1")
	// if err != nil {
	// 	fmt.Printf("etcd get fail,err is %v", err)
	// }

	// rch := Client.Watch(context.Background(), "key1")
	// for wresp := range rch {
	// 	for _, event := range wresp.Events {
	// 		fmt.Printf("type:%s key:%s value:%s\n", event.Type, event.Kv.Key, event.Kv.Value)
	// 	}
	// }

	// for _, ev := range gr.Kvs {
	// 	fmt.Printf("%s:%s\n", ev.Key, ev.Value)
	// }
	// cancel()
	return
}
func Write() {
	str := `[{"path":"/usr/local/test.log","topic":"web_log"},{"path":"/usr/local/test2.log","topic":"s4_log"}]`
	//str := `[{"path":"/usr/local/test.log","topic":"web_log"},{"path":"/usr/local/test3.log","topic":"new_log"},{"path":"/usr/local/test2.log","topic":"s4_log"}]`
	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
	_, err := Client.Put(ctx, "collect_log_conf", str)
	if err != nil {
		fmt.Printf("etcd send fail,err is %v", err)
	}
	cancel()
}

func GetConf(key string) (collectEnrtyList []common.CollectEntry, err error) {
	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
	defer cancel()
	gr, err := Client.Get(ctx, key)
	if err != nil {
		fmt.Printf("etcd get conf from etcd fail,err is %v\n", err)
		return
	}
	if len(gr.Kvs) == 0 {
		fmt.Printf("get len:0 conf from etcd by,err is %v\n", err)
		return
	}
	ret := gr.Kvs[0]
	fmt.Println(ret.Value)
	err = json.Unmarshal(ret.Value, &collectEnrtyList)
	if err != nil {
		fmt.Printf("json unmarshal failed,err is %v\n", err)
		return
	}
	return
}

func WatchConf(key string) {
	for {
		wCH := Client.Watch(context.Background(), key)

		for wresp := range wCH {
			fmt.Println("new conf is coming")
			for _, event := range wresp.Events {
				fmt.Printf("type:%s key:%s value:%s\n", event.Type, event.Kv.Key, event.Kv.Value)
				var newConf []common.CollectEntry
				if event.Type == clientv3.EventTypeDelete {
					fmt.Println("ETCD DELETE THE KEY")
					Tailfile.SendNewConf(newConf) //blocked
					continue
				}
				err := json.Unmarshal(event.Kv.Value, &newConf)
				if err != nil {
					fmt.Printf("json unmarshal new conf failed, err:%v\n", err)
					continue
				}
				//create new tailfile
				Tailfile.SendNewConf(newConf) //blocked

			}
		}
	}

}
